home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / ax25user.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  5KB  |  225 lines

  1. /* User interface subroutines for AX.25
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "config.h"
  6. #ifdef AX25
  7. #include "mbuf.h"
  8. #include "timer.h"
  9. #include "iface.h"
  10. #include "lapb.h"
  11. #include "ax25.h"
  12. #include "lapb.h"
  13. #include <ctype.h>
  14.  
  15. /* Open an AX.25 connection */
  16. struct ax25_cb *
  17. open_ax25(iface,local,remote,mode,window,r_upcall,t_upcall,s_upcall,user)
  18. struct iface *iface;    /* Interface */
  19. char *local;        /* Local address */
  20. char *remote;        /* Remote address */
  21. int mode;        /* active/passive/server */
  22. int16 window;        /* Window size in bytes */
  23. void (*r_upcall)__ARGS((struct ax25_cb *,int));    /* Receiver upcall handler */
  24. void (*t_upcall)__ARGS((struct ax25_cb *,int));    /* Transmitter upcall handler */
  25. void (*s_upcall)__ARGS((struct ax25_cb *,int,int));    /* State-change upcall handler */
  26. int user;        /* User linkage area */
  27. {
  28.     struct ax25_cb *axp;
  29.     char remtmp[AXALEN];
  30.  
  31.     if(remote == NULLCHAR){
  32.         remote = remtmp;
  33.         setcall(remote," ");
  34.     }
  35.     if((axp = find_ax25(local,remote,iface)) != NULLAX25 && axp->state != LAPB_DISCONNECTED)
  36.         return NULLAX25;    /* Only one to a customer */
  37.     if(axp == NULLAX25 && (axp = cr_ax25(local,remote,iface)) == NULLAX25)
  38.         return NULLAX25;
  39. /*
  40.     memcpy(axp->remote,remote,AXALEN);
  41.     memcpy(axp->local,local,AXALEN);
  42.  */
  43.     axp->window = window;
  44.     axp->r_upcall = r_upcall;
  45.     axp->t_upcall = t_upcall;
  46.     axp->s_upcall = s_upcall;
  47.     axp->user = user;
  48.  
  49.     switch(mode){
  50.     case AX_SERVER:
  51.         axp->flags.clone = 1;
  52.     case AX_PASSIVE:    /* Note fall-thru */
  53.         axp->state = LAPB_LISTEN;
  54.         return axp;
  55.     case AX_ACTIVE:
  56.         break;
  57.     }    
  58.     switch(axp->state){
  59.     case LAPB_DISCONNECTED:
  60.         est_link(axp);
  61.         lapbstate(axp,LAPB_SETUP);
  62.         break;
  63.     case LAPB_SETUP:
  64.         free_q(&axp->txq);
  65.         break;
  66.     case LAPB_DISCPENDING:    /* Ignore */
  67.         break;
  68.     case LAPB_RECOVERY:
  69.     case LAPB_CONNECTED:
  70.         free_q(&axp->txq);
  71.         est_link(axp);
  72.         lapbstate(axp,LAPB_SETUP);
  73.         break;
  74.     }
  75.     return axp;
  76. }
  77.  
  78. /* Send data on an AX.25 connection. Caller provides optional PID. If
  79.  * a PID is provided, then operate in stream mode, i.e., a large packet
  80.  * is automatically packetized into a series of paclen-sized data fields.
  81.  *
  82.  * If pid == -1, it is assumed the packet (which may actually be a queue
  83.  * of distinct packets) already has a PID on the front and it is passed
  84.  * through directly even if it is very large.
  85.  */
  86. int
  87. send_ax25(axp,bp,pid)
  88. struct ax25_cb *axp;
  89. struct mbuf *bp;
  90. int pid;
  91. {
  92.     struct mbuf *bp1;
  93.     int16 offset,len,size;
  94.  
  95.     if(axp == NULLAX25 || bp == NULLBUF) {
  96.         free_p(bp);
  97.         return -1;
  98.     }
  99.  
  100.     if(pid != -1){
  101.         offset = 0;
  102.         len = len_p(bp);
  103.         /* It is important that all the pushdowns be done before
  104.          * any part of the original packet is freed.
  105.          * Otherwise the pushdown might erroneously overwrite
  106.          * a part of the packet that had been duped and freed.
  107.          */
  108.         while(len != 0){
  109.             size = min(len,axp->paclen);
  110.             dup_p(&bp1,bp,offset,size);
  111.             len -= size;
  112.             offset += size;
  113.             bp1 = pushdown(bp1,1);
  114.             bp1->data[0] = pid;
  115.             enqueue(&axp->txq,bp1);
  116.         }
  117.         free_p(bp);
  118.     } else {
  119.         enqueue(&axp->txq,bp);
  120.     }
  121.     return lapb_output(axp);
  122. }
  123.  
  124. /* Receive incoming data on an AX.25 connection */
  125. struct mbuf *
  126. recv_ax25(axp,cnt)
  127. struct ax25_cb *axp;
  128. int16 cnt;
  129. {
  130.     struct mbuf *bp;
  131.  
  132.     if(axp->rxq == NULLBUF)
  133.         return NULLBUF;
  134.  
  135.     if(cnt == 0){
  136.         /* This means we want it all */
  137.         bp = axp->rxq;
  138.         axp->rxq = NULLBUF;
  139.     } else {
  140.         bp = ambufw(cnt);
  141.         bp->cnt = pullup(&axp->rxq,bp->data,cnt);
  142.     }
  143.     /* If this has un-busied us, send a RR to reopen the window */
  144.     if(len_p(axp->rxq) < axp->window
  145.      && (len_p(axp->rxq) + bp->cnt) >= axp->window)
  146.         sendctl(axp,LAPB_RESPONSE,RR);
  147.  
  148.     return bp;
  149. }
  150.  
  151. /* Close an AX.25 connection */
  152. int
  153. disc_ax25(axp)
  154. struct ax25_cb *axp;
  155. {
  156.     if(axp == NULLAX25)
  157.         return -1;
  158.     switch(axp->state){
  159.     case LAPB_DISCONNECTED:
  160.         break;        /* Ignored */
  161.     case LAPB_LISTEN:
  162.         del_ax25(axp);
  163.         break;
  164.     case LAPB_DISCPENDING:
  165.         lapbstate(axp,LAPB_DISCONNECTED);
  166.         break;
  167.     case LAPB_CONNECTED:
  168.     case LAPB_RECOVERY:
  169.         free_q(&axp->txq);
  170.         axp->retries = 0;
  171.         sendctl(axp,LAPB_COMMAND,DISC|PF);
  172.         stop_timer(&axp->t3);
  173.         start_timer(&axp->t1);
  174.         lapbstate(axp,LAPB_DISCPENDING);
  175.         break;
  176.     }
  177.     return 0;
  178. }
  179.  
  180. /* Verify that axp points to a valid ax25 control block */
  181. int
  182. ax25val(axp)
  183. struct ax25_cb *axp;
  184. {
  185.     register struct ax25_cb *axp1;
  186.  
  187.     if(axp == NULLAX25)
  188.         return 0;    /* Null pointer can't be valid */
  189.     for(axp1 = Ax25_cb;axp1 != NULLAX25; axp1 = axp1->next)
  190.         if(axp1 == axp)
  191.             return 1;
  192.     return 0;
  193. }
  194.  
  195. /* Force a retransmission */
  196. int
  197. kick_ax25(axp)
  198. struct ax25_cb *axp;
  199. {
  200.     if(!ax25val(axp))
  201.         return -1;
  202.     recover(axp);
  203.     return 0;
  204. }
  205.  
  206. /* Abruptly terminate an AX.25 connection */
  207. int
  208. reset_ax25(axp)
  209. struct ax25_cb *axp;
  210. {
  211.     void (*upcall)__ARGS((struct ax25_cb *,int,int));
  212.  
  213.     if(axp == NULLAX25)
  214.         return -1;
  215.     upcall = axp->s_upcall;
  216.     lapbstate(axp,LAPB_DISCONNECTED);
  217.     /* Clean up if the standard upcall isn't in use */
  218.     if(upcall != s_ascall)
  219.         del_ax25(axp);
  220.     return 0;
  221. }
  222.  
  223. #endif
  224.  
  225.